/* INDIVIDUAZIONE DEI MEZZI DI TRASPORTO PER SPOSTARSI TRA LE AREE DELL'ITINERARIO PIANIFICATO */
collegamentoMezzi:-
	findall(_,
			(areeGiorno(Giorno,Aree),
			collegaAree(Aree,Collegamenti),
			assert(collegamentiGiorno(Giorno,Collegamenti))),
		_)
	.
	

/* FORNISCE I MEZZI PER SPOSTARSI TRA LE AREE CONSECUTIVE DI UNA LISTA (caso base)*/
collegaAree(Aree,Collegamenti):-
	Aree=[A|[B|[]]],
	(collegamento(Id,A,B)->
		IdC=Id;
		(idCollegamento(IdC),
		 ultimoCollegamento(A,B),
		 selSitiDaCollegare(A,B,S1,S2),
		 ( (collega(S1,S2,Collegamento),!);
		   (collegaConScambio(S1,S2,Collegamento),!);
		   (collegamenti(IdF1,S1),collegamenti(IdF2,S2),collegaConScambi(IdF1,IdF2,3,Collegamento),!);
		   (Collegamento=[])	
		 ),
		 assert(collegamento(IdC,Collegamento))
		)
	),
	assert(collegamento(IdC,A,B)),
	Collegamenti=[IdC],
	odbc_transaction(commit).


/* FORNISCE I MEZZI PER SPOSTARSI TRA LE AREE CONSECUTIVE DI UNA LISTA */
collegaAree(Aree,Collegamenti):-
	Aree=[A|[B|AreeRest]],
	not(AreeRest=[]),
	collegaAree([B|AreeRest],CollegamentiRest),
	(collegamento(Id,A,B)->
		IdC=Id;
		(idCollegamento(IdC),
		 selSitiDaCollegare(A,B,S1,S2),
		 ( (collega(S1,S2,Collegamento),!);
		   (collegaConScambio(S1,S2,Collegamento),!);
		   (collegamenti(IdF1,S1),collegamenti(IdF2,S2),collegaConScambi(IdF1,IdF2,3,Collegamento))
		 ),
		 assert(collegamento(IdC,Collegamento))
		)
	),
	assert(collegamento(IdC,A,B)),
	append([IdC],CollegamentiRest,Collegamenti),
	odbc_transaction(commit).



/* FORNISCE IL MEZZO DI TRASPORTO DA UTILIZZARE PER SPOSTARSI DAL SITO S1 AL SITI S2*/
collega(S1,S2,Collegamento):-
	collegamenti(IdF1,S1),
	collegamenti(IdF2,S2),
	collegaConScambi(IdF1,IdF2,0,Collegamento),!.

/* FORNISCE I 2 MEZZI DI TRASPORTO DA UTILIZZARE PER SPOSTARSI DAL SITO S1 AL SITI S2*/
collegaConScambio(S1,S2,Collegamento):-
	collegamenti(IdF1,S1),
	collegamenti(IdF2,S2),
	collegaConScambi(IdF1,IdF2,1,Collegamento),!.


/* COLLEGAMENTO CON PIU' SCAMBI (caso base) */
collegaConScambi(IdF1,IdF2,Scambi,Collegamento):-
	Scambi=0,
	not(IdF1==IdF2),
	fermateMezzi(IdM,IdF1),
	fermateMezzi(IdM,IdF2),
	Collegamento=[IdF1,IdM,IdF2],!.

/* COLLEGAMENTO CON PIU' SCAMBI */
collegaConScambi(IdF1,IdF2,Scambi,Collegamento):-
	not(Scambi==0),
	not(IdF1==IdF2),	
	fermateMezzi(IdM,IdF1),
	not(fermateMezzi(IdM,IdF2)),
	fermateMezzi(IdM,IdF),
	not(IdF=IdF1),
	S is Scambi-1,
	collegaConScambi(IdF,IdF2,S,CollegamentoRest),
	append([IdF1,IdM],CollegamentoRest,Collegamento),!.
			

selSitiDaCollegare(A,B,Sa,Sb):-
	percorso(B,Pb),
	length(Pb,Lb),
	ith(Lb,Pb,Sb),
	percorso(A,Pa),
	length(Pa,La),
	ith(1,Pa,S1),
	ith(La,Pa,S2),
	distanzaSiti(Sb,S1,D1),
	distanzaSiti(Sb,S2,D2),
	(D1<D2->
		(Sa=S1);
		(Sa=S2,
		 reverse(Pa,PaN),
		 retract(percorso(A,Pa)),
		 assert(percorso(A,PaN))
		)
	).

ultimoCollegamento(A,B):-
	percorso(A,Pa),
	length(Pa,La),
	ith(La,Pa,Sa),
	percorso(B,Pb),
	length(Pb,Lb),
	ith(1,Pb,S1),
	ith(Lb,Pb,S2),
	distanzaSiti(Sa,S1,D1),
	distanzaSiti(Sa,S2,D2),
	(D1>D2->
		(reverse(Pb,PbN),
		 retract(percorso(B,Pb)),
		 assert(percorso(B,PbN))
		)
	).


/* IDENTIFICATIVO DI UN NUOVO COLLEGAMENTO */
idCollegamento(ID):-
	idc(IDC),
	ID is +(IDC,1),
	retract(idc(IDC)),
	assert(idc(ID)).




